#include "ColorPickerWidget.h"

#include "Widgets/RectangleWidget.h"
#include "Widgets/TextWidget.h"
#include "Widgets/ButtonWidget.h"
#include "Widgets/SpinBox.h"
#include "Widgets/Positioners/HorizontalPositionerWidget.h"
#include "Widgets/Positioners/VerticalPositionerWidget.h"

RColorPickerWidget::RColorPickerWidget()
{
    auto VerticalPositioner=NewWidget<RVerticalPositionerWidget>(this);
    VerticalPositioner->Anchor.Fill(this);

    Preview= NewWidget<RRectangleWidget>(VerticalPositioner);
    Preview->Anchor.HorizontalFill(VerticalPositioner);
    Preview->Height=20;
    Preview->FillColor=[this]()->SColor{
        return Color;
    };

    auto RHorizontalPositioner=NewWidget<RHorizontalPositionerWidget>(VerticalPositioner);
    RHorizontalPositioner->Anchor.HorizontalFill(VerticalPositioner);
    RHorizontalPositioner->Height=20;

    auto RLabel=NewWidget<RTextWidget>(RHorizontalPositioner);
    RLabel->Anchor.VerticalFill(RHorizontalPositioner);
    RLabel->Text=U"R";
    RLabel->HorizontalAlignment=ETextHorizontalAlignment::Left;
    RLabel->VerticalAlignment=ETextVerticalAlignment::Center;

    R=NewWidget<RSpinBox>(RHorizontalPositioner);
    R->Anchor.VerticalFill(RHorizontalPositioner);
    R->Anchor.LeftReference=RLabel;
    R->Anchor.LeftReferenceEdge=EHorizontalWidgetEdge::Right;
    R->Anchor.LeftOffset=5;
    R->HorizontalAlignment=ETextHorizontalAlignment::Left;
    R->VerticalAlignment=ETextVerticalAlignment::Center;
    R->SetNumber(255);
    R->SetMinNumber(0);
    R->SetMaxNumber(255);
    R->OnNumberAccepted.BindLambda([this](float NewNum){
        Color.R=(uint8_t)NewNum /255;
    });


    auto GHorizontalPositioner=NewWidget<RHorizontalPositionerWidget>(VerticalPositioner);
    GHorizontalPositioner->Anchor.HorizontalFill(VerticalPositioner);
    GHorizontalPositioner->Height=20;

    auto GLabel=NewWidget<RTextWidget>(GHorizontalPositioner);
    GLabel->Anchor.VerticalFill(GHorizontalPositioner);
    GLabel->Text=U"G";
    GLabel->HorizontalAlignment=ETextHorizontalAlignment::Left;
    GLabel->VerticalAlignment=ETextVerticalAlignment::Center;

    G= NewWidget<RSpinBox>(GHorizontalPositioner);
    G->Anchor.VerticalFill(GHorizontalPositioner);
    G->Anchor.LeftReference=GLabel;
    G->Anchor.LeftReferenceEdge=EHorizontalWidgetEdge::Right;
    G->Anchor.LeftOffset=5;
    G->HorizontalAlignment=ETextHorizontalAlignment::Left;
    G->VerticalAlignment=ETextVerticalAlignment::Center;
    G->SetNumber(255);
    G->SetMinNumber(0);
    G->SetMaxNumber(255);
    G->OnNumberAccepted.BindLambda([this](float NewNum){
        Color.G=(uint8_t)NewNum /255;
    });

    auto BHorizontalPositioner=NewWidget<RHorizontalPositionerWidget>(VerticalPositioner);
    BHorizontalPositioner->Anchor.HorizontalFill(VerticalPositioner);
    BHorizontalPositioner->Height=20;

    auto BLabel=NewWidget<RTextWidget>(BHorizontalPositioner);
    BLabel->Anchor.VerticalFill(BHorizontalPositioner);
    BLabel->Text=U"B";
    BLabel->HorizontalAlignment=ETextHorizontalAlignment::Left;
    BLabel->VerticalAlignment=ETextVerticalAlignment::Center;

    B= NewWidget<RSpinBox>(BHorizontalPositioner);
    B->Anchor.VerticalFill(BHorizontalPositioner);
    B->Anchor.LeftReference=BLabel;
    B->Anchor.LeftReferenceEdge=EHorizontalWidgetEdge::Right;
    B->Anchor.LeftOffset=5;
    B->HorizontalAlignment=ETextHorizontalAlignment::Left;
    B->VerticalAlignment=ETextVerticalAlignment::Center;
    B->SetNumber(255);
    B->SetMinNumber(0);
    B->SetMaxNumber(255);
    B->OnNumberAccepted.BindLambda([this](float NewNum){
        Color.B=(uint8_t)NewNum /255;
    });

    auto AHorizontalPositioner=NewWidget<RHorizontalPositionerWidget>(VerticalPositioner);
    AHorizontalPositioner->Anchor.HorizontalFill(VerticalPositioner);
    AHorizontalPositioner->Height=20;

    auto ALabel=NewWidget<RTextWidget>(AHorizontalPositioner);
    ALabel->Anchor.VerticalFill(AHorizontalPositioner);
    ALabel->Text=U"A";
    ALabel->HorizontalAlignment=ETextHorizontalAlignment::Left;
    ALabel->VerticalAlignment=ETextVerticalAlignment::Center;

    A= NewWidget<RSpinBox>(AHorizontalPositioner);
    A->Anchor.VerticalFill(AHorizontalPositioner);
    A->Anchor.LeftReference=ALabel;
    A->Anchor.LeftReferenceEdge=EHorizontalWidgetEdge::Right;
    A->Anchor.LeftOffset=5;
    A->HorizontalAlignment=ETextHorizontalAlignment::Left;
    A->VerticalAlignment=ETextVerticalAlignment::Center;
    A->SetNumber(255);
    A->SetMinNumber(0);
    A->SetMaxNumber(255);
    A->OnNumberAccepted.BindLambda([this](float NewNum){
        Color.A=(uint8_t)NewNum /255;
    });
    

    //create confirm button
    auto ConfirmButton=NewWidget<RButtonWidget>(VerticalPositioner);
    ConfirmButton->Width=60;
    ConfirmButton->Height=20;
    ConfirmButton->Text=U"Confirm";
    ConfirmButton->OnClicked.BindLambda([this](const SMouseButtonEvent&)->bool{
        OnColorConfirmed.ExecuteIfBound(this->GetColor());
        return true;
    });
}

void RColorPickerWidget::SetColor(const SColor &InColor)
{
    Color=InColor;
    R->SetNumber(Color.R*255);
    G->SetNumber(Color.G*255);
    B->SetNumber(Color.B*255);
    A->SetNumber(Color.A*255);
}

SColor RColorPickerWidget::GetColor() const
{
    return Color;
}
